﻿
#include "OiPCH.hpp"
#include <QtCharts/QChart>
#include <QtCharts/QValueAxis>

namespace Oi
{
    using namespace PLScannerCore;
    static QFont getFont(int size)
    {
        QFont font;
        font.setPixelSize(size);
        return font;
    }
    namespace PLScannerDll
    {
        class PlyPageImpl : public Impl<PlyPage>
        {
        public:
            void init();
            void updateParams();
            void updateTol(ValueLabel* label, int index, QString key);
            void updateTol(double& upper, double& lower, int index, QString key);
            void setTitalLable(QLabel* pLable, int backColor = 0);
            void InitChartViewer();
        public:
            QGridLayout* _mainLayout = nullptr;

        public: 
            ProductParams _params;
            DataRow _lastRow;
        public:
            ValueLabel* _width;
            ValueLabel* _width1;
            ValueLabel* _thickness1;
            ValueLabel* _thickness2;
            ValueLabel* _thickness3;
            ValueLabel* _thickness4;
            ValueLabel* _thickness5;
            double _widthStd;
            double _widthTol;
            double _thickness1Std;
            double _thickness1Tol;
            double _thickness2Std;
            double _thickness2Tol;
            double _thickness3Std;
            double _thickness3Tol;
            double _thickness4Std;
            double _thickness4Tol;
            double _thickness5Std;
            double _thickness5Tol;

        public:
            QMap<ValueLabel*, double> warningValue;
            QMap<ValueLabel*, double> errorValue;
            double _errorThicknessRange;
            double _errorWidthRange;
            double _edgeThickness;
            double _midThicknessWT;
            double _midThicknessET;
            int    _precision;
            QLabel* _pPlcWidth;
            QLabel* _pPlcWidthEl;
            QLabel* _pPlcPoint1;
            QLabel* _pPlcPoint2;
            QLabel* _pPlcPoint3;
            QLabel* _pPlcPoint4;
            QLabel* _pPlcPoint5;
            QLabel* _pMeasureWidth;
            QLabel* _pMeasureWidthEl;
            QLabel* _pMeasurePoint1;
            QLabel* _pMeasurePoint2;
            QLabel* _pMeasurePoint3;
            QLabel* _pMeasurePoint4;
            QLabel* _pMeasurePoint5;
            MyChartViewer* _opChart;
            MyChartViewer* _dsChart;
            MyChartViewer* _widthChart;
        };

        void PlyPageImpl::init()
        {
            OI_Q(PlyPage);
            _mainLayout = new QGridLayout(q);
            QFont font;
            font.setPixelSize(35);
            QLabel* pStdPlc = new QLabel(q);
            pStdPlc->setAlignment(Qt::AlignCenter);
            pStdPlc->setText("标准值");
            pStdPlc->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pStdPlc->setFont(font);      
            _pPlcWidth = new QLabel(q);
            _pPlcWidth->setAlignment(Qt::AlignCenter);
            _pPlcWidth->setText("");
            _pPlcWidth->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcWidth->setFont(font);
            _pPlcWidthEl = new QLabel(q);
            _pPlcWidthEl->setAlignment(Qt::AlignCenter);
            _pPlcWidthEl->setText("");
            _pPlcWidthEl->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcWidthEl->setFont(font);
            _pPlcPoint1 = new QLabel(q);
            _pPlcPoint1->setAlignment(Qt::AlignCenter);
            _pPlcPoint1->setText("标准：");
            _pPlcPoint1->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcPoint1->setFont(font);
            _pPlcPoint2 = new QLabel(q);
            _pPlcPoint2->setAlignment(Qt::AlignCenter);
            _pPlcPoint2->setText("标准：");
            _pPlcPoint2->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcPoint2->setFont(font);
            _pPlcPoint3 = new QLabel(q);
            _pPlcPoint3->setAlignment(Qt::AlignCenter);
            _pPlcPoint3->setText("标准：");
            _pPlcPoint3->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcPoint3->setFont(font);
            _pPlcPoint4 = new QLabel(q);
            _pPlcPoint4->setAlignment(Qt::AlignCenter);
            _pPlcPoint4->setText("标准：");
            _pPlcPoint4->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcPoint4->setFont(font);
            _pPlcPoint5 = new QLabel(q);
            _pPlcPoint5->setAlignment(Qt::AlignCenter);
            _pPlcPoint5->setText("标准：");
            _pPlcPoint5->setStyleSheet("QLabel{color: black;background-color: yellow;border-style: groove;border-radius:10px;}");
            _pPlcPoint5->setFont(font);

            QLabel* pTypeLable = new QLabel(q);
            pTypeLable->setAlignment(Qt::AlignCenter);
            pTypeLable->setText("分类");
            pTypeLable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pTypeLable->setFont(font);
            QLabel* pMeasureWidthLable = new QLabel(q);
            pMeasureWidthLable->setAlignment(Qt::AlignCenter);
            pMeasureWidthLable->setText("总宽度");
            pMeasureWidthLable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasureWidthLable->setFont(font);
            QLabel* pMeasureWidthElLable = new QLabel(q);
            pMeasureWidthElLable->setAlignment(Qt::AlignCenter);
            pMeasureWidthElLable->setText("1P宽度");
            pMeasureWidthElLable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasureWidthElLable->setFont(font);
            QLabel* pMeasurePoint1Lable = new QLabel(q);
            pMeasurePoint1Lable->setAlignment(Qt::AlignCenter);
            pMeasurePoint1Lable->setText("OP侧2P厚度");
            pMeasurePoint1Lable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasurePoint1Lable->setFont(font);
            QLabel* pMeasurePoint2Lable = new QLabel(q);
            pMeasurePoint2Lable->setAlignment(Qt::AlignCenter);
            pMeasurePoint2Lable->setText("OP侧肩部厚度");
            pMeasurePoint2Lable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasurePoint2Lable->setFont(font);
            QLabel* pMeasurePoint3Lable = new QLabel(q);
            pMeasurePoint3Lable->setAlignment(Qt::AlignCenter);
            pMeasurePoint3Lable->setText("中间厚度");
            pMeasurePoint3Lable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasurePoint3Lable->setFont(font);
            QLabel* pMeasurePoint4Lable = new QLabel(q);
            pMeasurePoint4Lable->setAlignment(Qt::AlignCenter);
            pMeasurePoint4Lable->setText("DR侧肩部厚度");
            pMeasurePoint4Lable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasurePoint4Lable->setFont(font);
            QLabel* pMeasurePoint5Lable = new QLabel(q);
            pMeasurePoint5Lable->setAlignment(Qt::AlignCenter);
            pMeasurePoint5Lable->setText("DR侧2P厚度");
            pMeasurePoint5Lable->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pMeasurePoint5Lable->setFont(font);

            font.setPixelSize(35);
            QLabel* pStdMeasure = new QLabel(q);
            pStdMeasure->setAlignment(Qt::AlignCenter);
            pStdMeasure->setText("实测值");
            pStdMeasure->setStyleSheet("QLabel{color: white;background-color: black;border-style: groove;border-radius:10px;}");
            pStdMeasure->setFont(font);
            _pMeasureWidth = new QLabel(q);
            _pMeasureWidth->setText("");
            _pMeasureWidth->setFont(font);
            _pMeasureWidth->setAlignment(Qt::AlignCenter);
            _pMeasureWidth->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasureWidthEl = new QLabel(q);
            _pMeasureWidthEl->setText("");
            _pMeasureWidthEl->setFont(font);
            _pMeasureWidthEl->setAlignment(Qt::AlignCenter);
            _pMeasureWidthEl->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasurePoint1 = new QLabel(q);
            _pMeasurePoint1->setText("");
            _pMeasurePoint1->setFont(font);
            _pMeasurePoint1->setAlignment(Qt::AlignCenter);
            _pMeasurePoint1->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasurePoint2 = new QLabel(q);
            _pMeasurePoint2->setText("");
            _pMeasurePoint2->setFont(font);
            _pMeasurePoint2->setAlignment(Qt::AlignCenter);
            _pMeasurePoint2->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasurePoint3 = new QLabel(q);
            _pMeasurePoint3->setText("");
            _pMeasurePoint3->setFont(font);
            _pMeasurePoint3->setAlignment(Qt::AlignCenter);
            _pMeasurePoint3->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasurePoint4 = new QLabel(q);
            _pMeasurePoint4->setText("");
            _pMeasurePoint4->setFont(font);
            _pMeasurePoint4->setAlignment(Qt::AlignCenter);
            _pMeasurePoint4->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
            _pMeasurePoint5 = new QLabel(q);
            _pMeasurePoint5->setText("");
            _pMeasurePoint5->setFont(font);
            _pMeasurePoint5->setAlignment(Qt::AlignCenter);
            _pMeasurePoint5->setStyleSheet("QLabel{color: white;background-color: green;border-style: groove;border-radius:10px;}");
             
            _mainLayout->addWidget(pTypeLable, 0, 0, 1, 1);
            _mainLayout->addWidget(pMeasureWidthLable, 0, 1, 1, 1);
            _mainLayout->addWidget(pMeasureWidthElLable, 0, 2, 1, 1);
            _mainLayout->addWidget(pMeasurePoint1Lable, 0, 3, 1, 1);
            _mainLayout->addWidget(pMeasurePoint2Lable, 0, 4, 1, 1);
            _mainLayout->addWidget(pMeasurePoint3Lable, 0, 5, 1, 1);
            _mainLayout->addWidget(pMeasurePoint4Lable, 0, 6, 1, 1);
            _mainLayout->addWidget(pMeasurePoint5Lable, 0, 7, 1, 1);

            _mainLayout->addWidget(pStdPlc,     1, 0, 1, 1);
            _mainLayout->addWidget(_pPlcWidth,  1, 1, 1, 1);
            _mainLayout->addWidget(_pPlcWidthEl, 1, 2, 1, 1);
            _mainLayout->addWidget(_pPlcPoint1, 1, 3, 1, 1);
            _mainLayout->addWidget(_pPlcPoint2, 1, 4, 1, 1);
            _mainLayout->addWidget(_pPlcPoint3, 1, 5, 1, 1);
            _mainLayout->addWidget(_pPlcPoint4, 1, 6, 1, 1);
            _mainLayout->addWidget(_pPlcPoint5, 1, 7, 1, 1);

            _mainLayout->addWidget(pStdMeasure,     2, 0, 2, 1);
            _mainLayout->addWidget(_pMeasureWidth,  2, 1, 2, 1);
            _mainLayout->addWidget(_pMeasureWidthEl, 2, 2, 2, 1);
            _mainLayout->addWidget(_pMeasurePoint1, 2, 3, 2, 1);
            _mainLayout->addWidget(_pMeasurePoint2, 2, 4, 2, 1);
            _mainLayout->addWidget(_pMeasurePoint3, 2, 5, 2, 1);
            _mainLayout->addWidget(_pMeasurePoint4, 2, 6, 2, 1);
            _mainLayout->addWidget(_pMeasurePoint5, 2, 7, 2, 1);
            QMetaObject::invokeMethod(q, "onReady");
        }
        void PlyPageImpl::setTitalLable(QLabel* pLable,int backColor)
        {
            pLable->setFont(getFont(27));
            pLable->setFixedSize(200, 35);
            pLable->setAlignment(Qt::AlignCenter);
            if (backColor == 0)
            {
                pLable->setStyleSheet("QLabel{color: black;border-style: groove;border-radius:5px;}");
            }
            else if (backColor == 1)
            {
                pLable->setStyleSheet("QLabel{color: black;background-color: white;border-style: groove;border-radius:5px;}");
            }
            else if(backColor == 2)
            {
                pLable->setStyleSheet("QLabel{color: black;background-color: green;border-style: groove;border-radius:5px;}");
            }
            else if (backColor == 3)
            {
                pLable->setStyleSheet("QLabel{color: black;background-color: rgb(102, 204, 240);border-style: groove;border-radius:5px;}");
            }
            pLable->setFrameShape(QFrame::Box);
            pLable->setFrameShadow(QFrame::Raised);
        }

        void PlyPageImpl::InitChartViewer()
        {
            _opChart = new MyChartViewer(20);
            _opChart->AddChart(2);
            _opChart->setDefaultName("op");
            _opChart->setTheme(QChart::ChartThemeDark);
            _dsChart = new MyChartViewer(30);
            _dsChart->AddChart(3);
            _dsChart->setDefaultName("mid");
            _dsChart->setTheme(QChart::ChartThemeDark);
            _widthChart = new MyChartViewer(10);
            _widthChart->AddChart(1);
            _widthChart->setDefaultName("width");
            _widthChart->setTheme(QChart::ChartThemeDark);
            if (_opChart)
            {
                _mainLayout->addWidget(_opChart, 5, 0, 4, 4);
            }
            if (_dsChart)
            {
                _mainLayout->addWidget(_dsChart, 5, 4, 4, 4);
            }
            if (_widthChart)
            {
                _mainLayout->addWidget(_widthChart, 9, 0, 4, 8);
            }
        }

        void PlyPageImpl::updateParams()
        {
            OI_Q(PlyPage);
            if (_opChart)
            {
                _opChart->clearViewer();
                delete _opChart;
                _opChart = NULL;
            }
            if (_dsChart)
            {
                _dsChart->clearViewer();
                delete _dsChart;
                _dsChart = NULL;
            }

            if (_widthChart)
            {
                _widthChart->clearViewer();
                delete _widthChart;
                _widthChart = NULL;
            }
            
            double thick = _params.fixedPoint.y();
            _pPlcWidth->setText(QString::number(_params.materialsWidth));
            _pPlcWidthEl->setText(QString::number(_params.materialsUpWidth));
            _pPlcPoint1->setText(QString::number(_params.materialsThickness));
            _pPlcPoint2->setText(QString::number(thick));
            _pPlcPoint3->setText(QString::number(thick));
            _pPlcPoint4->setText(QString::number(thick));
            _pPlcPoint5->setText(QString::number(_params.materialsThickness));
            InitChartViewer();
            _opChart->setRange(_params.materialsThickness + PLScanner::instance()->thicknessETDefault, _params.materialsThickness - PLScanner::instance()->thicknessETDefault);
            double et = PLScanner::instance()->midThicknessETDefault;
            _dsChart->setRange(thick + PLScanner::instance()->midThicknessETDefault, thick - PLScanner::instance()->midThicknessETDefault);
            _widthChart->setRange(_params.materialsWidth + PLScanner::instance()->widthETDefault, _params.materialsWidth - PLScanner::instance()->widthETDefault);
        }

        void PlyPageImpl::updateTol(ValueLabel* label, int index, QString key)
        {
            int enable = 0;
            double warningTol = 0.0;
            double errorTol = 0.0;
            double stdValue = 0.0;

            if (_params.getMeasureEnable(index, key, enable) &&
                _params.getMeasureWarningTol(index, key, warningTol) &&
                _params.getMeasureErrorTol(index, key, errorTol) &&
                _params.getStdValue(index, key, stdValue))
            {
                label->setEnabled(true);
                if (enable & TC_WarningEnable)
                {
                    label->setEarlyUpper(stdValue + warningTol);
                    label->setEarlyLower(stdValue - warningTol);
                    warningValue[label] = warningTol;
                }

                if (enable & TC_ErrorEnable)
                {
                    label->setUpper(stdValue + errorTol);
                    label->setLower(stdValue - errorTol);
                    errorValue[label] = errorTol;
                }

                label->setStdValue(stdValue);
            }
            else
            {
                label->setEnabled(false);
            }
        }

        void PlyPageImpl::updateTol(double& std, double& err, int index, QString key)
        {
            double errorTol = 0.0;
            double stdValue = 0.0;

            if (_params.getMeasureErrorTol(index, key, errorTol) &&
                _params.getStdValue(index, key, stdValue))
            {
                err = errorTol;
                std = stdValue;
            }
            else
            {
                std = 0;
                err = 0;
            }
        }

        PlyPage::PlyPage(QWidget * parent /*= nullptr*/)
            : PageAbstract(parent)
        {
            OI_I(PlyPage)->init();
        }

        void PlyPage::setParams(const ProductParams& params)
        {
            OI_F(PlyPage);
            d->_params = params;
            d->updateParams();
        }

        int PlyPage::setResult(const PLScannerCore::WorkResult::Result& result)
        {
            OI_F(PlyPage);
            int resultCode = result.result;
            PLScannerCore::WorkResult::Result resultTemp = result;
            DataRow row;

            row.widthErr = d->_widthTol;
            double v1 = 0.0, v2 = 0.0, v3 = 0.0, v4 = 0.0, v5 = 0.0;
            double dwidth = 0.0, dwidthEl = 0.0;;
            auto rdata = result.data;
            if (rdata.contains("tolWidth"))
            {
                double tolWidth = rdata["tolWidth"].toDouble();
                QString strValue = QString::number(tolWidth, 'f', 2);
                if (d->_pMeasureWidth)
                {
                    d->_pMeasureWidth->setText(strValue);
                }
                dwidth = strValue.toDouble();
            }
            if (rdata.contains("tolWidthEl"))
            {
                double tolWidthEl = rdata["tolWidthEl"].toDouble();

                QString strValue = QString::number(tolWidthEl, 'f', 2);

                dwidthEl = strValue.toDouble();
                if (d->_pMeasureWidthEl)
                {
                    d->_pMeasureWidthEl->setText(strValue);
                }
            }
            if (rdata.contains("measureThickness"))
            {
                QList<QPointF> values = rdata["measureThickness"].value<QList<QPointF>>();
                if (values.size() > 4)
                {                
                    v1 = values[0].y();
                    QString strValue = QString::number(v1, 'f', 2);
                    if (d->_pMeasurePoint1)
                    {
                        d->_pMeasurePoint1->setText(strValue);
                    }
                    v2 = values[1].y();
                    strValue = QString::number(v2, 'f', 2);
                    if (d->_pMeasurePoint2)
                    {
                        d->_pMeasurePoint2->setText(strValue);
                    }
                    v3 = values[2].y();
                    strValue = QString::number(v3, 'f', 2);
                    if (d->_pMeasurePoint3)
                    {
                        d->_pMeasurePoint3->setText(strValue);
                    }
                    v4 = values[3].y();
                    strValue = QString::number(v4, 'f', 2);
                    if (d->_pMeasurePoint4)
                    {
                        d->_pMeasurePoint4->setText(strValue);
                    }
                    v5 = values[4].y();
                    strValue = QString::number(v5, 'f', 2);
                    if (d->_pMeasurePoint5)
                    {
                        d->_pMeasurePoint5->setText(strValue);
                    }
                }
            }
            //更新趋势图
            std::vector<double> vecWidth;
            vecWidth.clear();
            vecWidth.push_back(dwidth);
            d->_widthChart->DrawLine(vecWidth, d->_params.materialsWidth, PLScanner::instance()->widthETDefault);
            std::vector<double> vecPos;
            vecPos.clear();
            vecPos.push_back(v1);
            vecPos.push_back(v5);
            d->_opChart->DrawLine(vecPos, d->_params.materialsThickness, PLScanner::instance()->thicknessETDefault);
            std::vector<double> vecMid;
            vecMid.clear();
            vecMid.push_back(v2);
            vecMid.push_back(v3);
            vecMid.push_back(v4);
            d->_dsChart->DrawLine(vecMid, d->_params.fixedPoint.y(), PLScanner::instance()->midThicknessETDefault);
            row.result = resultCode;
            row.datetime = QDateTime::currentDateTime();
            row.formula = d->_params.specName;
            row.widthElStd = d->_params.materialsUpWidth;
            row.widthStd = d->_params.materialsWidth;
            row.thickness1Std = d->_params.materialsThickness;
            row.thickness2Std = d->_params.fixedPoint.y();
            row.thickness1 = v1;
            row.thickness2 = v2;
            row.thickness3 = v3;
            row.thickness4 = v4;
            row.thickness5 = v5;
            row.width = dwidth;
            row.widthEl = dwidthEl;
            row.user = UserManage::instance()->current();
            row.team = UserManage::instance()->team();
            row.widthErr = d->_widthTol;
            d->_lastRow = row;
            Database::instance()->insert(row);

            if (resultCode == WorkResult::RC_Success)
            {
                Motor::instance()->setResult(1);
            }
            else if (resultCode == WorkResult::RC_Warning)
            {
                Motor::instance()->setResult(0);
            }
            else
            {
                Motor::instance()->setResult(2);
            }

            auto outputSystem = Core::OiSettings()->value("System/OutputSystem").toString();
            if (outputSystem == "OPC")
            {
                if (PLScannerOutput::saveToSys(resultTemp, outputSystem))
                {

                }
            }
            else
            {
                if (PLScannerOutput::saveToSys(row, outputSystem))
                {

                }
            }


            return resultCode;
        }

        void PlyPage::onReady()
        {
            OI_F(PlyPage);
            //d->_profile->zoomFit();
            //d->_tread->zoomFit();
        }

        void PlyPage::resizeEvent(QResizeEvent *event)
        {
            OI_F(PlyPage);
            //d->_profile->zoomFit();
            //d->_tread->zoomFit();
        }

        void PlyPage::setRun(bool flag)
        {
            OI_F(PlyPage);
        }

        void PlyPage::toCurrent()
        {
            OI_F(PlyPage);
        }
    }
}